/*
RetroLeague - Mobile application for The Retro League Podcast
Copyright (C) 2010-2013 Hugues Johnson

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software 
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

package com.huguesjohnson.retroleague.episode;

import java.util.ArrayList;
import java.util.Date;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.huguesjohnson.retroleague.StreamEntry;
import com.huguesjohnson.retroleague.StreamEntry.Sources;
import com.huguesjohnson.retroleague.util.BruteForceDateParser;

import android.util.Log;

public class EpisodeParserHandler extends DefaultHandler{
	private static final String TAG="EpisodeParserHandler";
	private final static String TAG_ITEM="item";
	private final static String TAG_TITLE="title";
	private final static String TAG_ENCLOSURE="enclosure";
	private final static String TAG_DESCRIPTION="description";
	private final static String TAG_PUBDATE="pubDate";
	private final static String TAG_LINK="link";
	private ArrayList<StreamEntry> episodeList=new ArrayList<StreamEntry>();
	private StreamEntry currentEpisode=null;
    private StringBuilder characters=new StringBuilder();
    private boolean readThis=false;
    private BruteForceDateParser dateParser;
    private Date minimumDate;
    private static String bgColor="#000011";
    private static String fontColor="#ffffff";
    //for performance troubleshooting
    long startTime;
    long endTime;
    
    public EpisodeParserHandler(Date minimumDate){
    	super();
    	this.minimumDate=minimumDate;
    	this.dateParser=BruteForceDateParser.getInstance();
    	
    }
    
	public ArrayList<StreamEntry> getEpisodeList(){
		return(this.episodeList);
	}
	
	@Override
	public void startDocument() throws SAXException{
		super.startDocument();
	}

    @Override
    public void characters(char[] ch,int start,int length) throws SAXException{
        super.characters(ch,start,length);
        if(readThis){
        	this.characters.append(ch,start,length);
    	}
    }
	
	@Override
	public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException{
		super.startElement(uri,localName,qName,attributes);
		startTime=System.currentTimeMillis();
		String tagName=localName;
		Log.d(TAG,"startElement:"+tagName+":"+startTime);
		if((tagName==null)||(tagName.length()<1)){
			tagName=qName;
		}
		if(tagName.equalsIgnoreCase(TAG_ITEM)){
			this.currentEpisode=new StreamEntry();
			this.currentEpisode.setSource(Sources.Podcast);
		}
		if(this.currentEpisode!=null){
			if(tagName.equalsIgnoreCase(TAG_ENCLOSURE)){
				this.currentEpisode.setDownloadUrl(attributes.getValue("url"));
				try{
					this.currentEpisode.setDownloadLength(Integer.parseInt(attributes.getValue("length")));
				}catch(NumberFormatException nfx){
					Log.e("EpisodeParserHandler","error parsing enclosure length for episode: "+this.currentEpisode.getTitle(),nfx);
				}
			}else if(tagName.equalsIgnoreCase(TAG_TITLE)){
				readThis=true;
				this.characters.setLength(0);
			}else if(tagName.equalsIgnoreCase(TAG_DESCRIPTION)){
				readThis=true;
				this.characters.setLength(0);
			}else if(tagName.equalsIgnoreCase(TAG_PUBDATE)){
				readThis=true;
				this.characters.setLength(0);
			}else if(tagName.equalsIgnoreCase(TAG_LINK)){
				readThis=true;
				this.characters.setLength(0);
			}
		}
	}

	@Override
	public void endElement(String uri,String localName,String qName) throws SAXException{
		super.endElement(uri,localName,qName);
		String tagName=localName;
		endTime=System.currentTimeMillis();
		Log.d(TAG,"endElement:"+tagName+":"+endTime);
		Log.d(TAG,"parseTime:"+(endTime-startTime));
		if((tagName==null)||(tagName.length()<1)){
			tagName=qName;
		}
		if(this.currentEpisode!=null){
			if(tagName.equalsIgnoreCase(TAG_ITEM)){
				if((this.currentEpisode.getDownloadUrl()!=null)&&(this.currentEpisode.getDownloadUrl().length()>0)&&(this.currentEpisode.getPostedDate().compareTo(this.minimumDate)>0)){
					this.episodeList.add(this.currentEpisode);
				}
			}else if(tagName.equalsIgnoreCase(TAG_TITLE)){
				this.currentEpisode.setTitle(this.characters.toString());
				readThis=false;
			}else if(tagName.equalsIgnoreCase(TAG_DESCRIPTION)){
				StringBuffer content=new StringBuffer();
	            content.append("<html><body bgcolor='");
	            content.append(bgColor);
	            content.append("'><font color='");
	            content.append(fontColor);
	            content.append("'>");
				content.append(this.characters.toString());
				content.append("</font></body></html>");
				//fix youtube link & image
				int indexOf=content.indexOf("src=\"//www.youtube");
				if(indexOf>1){
					content.insert(indexOf+5,"http:");
				}
				indexOf=content.indexOf("src=\"//s.ytimg.com");
				if(indexOf>1){
					content.insert(indexOf+5,"http:");
				}
				//all done
				this.currentEpisode.setContent(content.toString());
				readThis=false;
			}else if(tagName.equalsIgnoreCase(TAG_PUBDATE)){
				String sDate=this.characters.toString();
				this.currentEpisode.setPostedDate(this.dateParser.parseDate(sDate));
				readThis=false;
			}else if(tagName.equalsIgnoreCase(TAG_LINK)){
				this.currentEpisode.setUrl(this.characters.toString());
				readThis=false;
			}
		}
	}
}